package com.ccnode.codegenerator.taikaoback.controller;

import com.ccnode.codegenerator.taikaoback.entity.Request.ResetPasswordRequest;
import com.ccnode.codegenerator.taikaoback.entity.Request.SendSmsRequest;
import com.ccnode.codegenerator.taikaoback.entity.User;
import com.ccnode.codegenerator.taikaoback.service.SmsService;
import com.ccnode.codegenerator.taikaoback.service.TokenService;
import com.ccnode.codegenerator.taikaoback.util.R;
import com.ccnode.codegenerator.taikaoback.entity.LoginUser;
import com.ccnode.codegenerator.taikaoback.service.UserService;
import com.ccnode.codegenerator.taikaoback.security.jwt.JwtUtil;
import com.ccnode.codegenerator.taikaoback.util.PasswordUtil;
import com.ccnode.codegenerator.taikaoback.util.UserContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;

import jakarta.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * 认证控制器
 */
@RestController
@RequestMapping("/api/auth")
public class AuthController {

    @Autowired
    private UserService userService;

    @Autowired
    private SmsService smsService;
    //注入redis模板
    @Autowired
    private StringRedisTemplate stringRedisTemplate;


    @Autowired
    private TokenService tokenService;
    
    @Autowired
    private AuthenticationManager authenticationManager;

    /**
     * 用户登录
     */
    @PostMapping("/login")
    public R<Map<String, Object>> login(@RequestBody LoginUser loginParams, HttpServletRequest request) {
        String id =  loginParams.getUserid();
        String password =  loginParams.getPassword();
        String  CaptchaCode = loginParams.getCaptcha();

        if(!stringRedisTemplate.hasKey(CaptchaCode)){
            return R.error(400, "验证码不正确！");
        }

        try {
            // 参数验证
            if (id == null || id.trim().isEmpty() || password == null || password.trim().isEmpty()) {
                return R.error(400, "用户ID和密码不能为空");
            }

            // 判断id是否是手机号
            User user;
            if (id.matches("^1[3-9]\\d{9}$")) {
                // 是手机号，通过手机号查找用户
                user = userService.getByPhone(id);
            } else {
                // 不是手机号，通过用户ID查找用户
                user = userService.getById(id);
            }

            // 检查用户是否存在
            if (user == null) {
                return R.error(400, "用户不存在");
            }

            // 使用Spring Security进行认证
            UsernamePasswordAuthenticationToken authenticationToken = 
                    new UsernamePasswordAuthenticationToken(user.getUname(), password);
            Authentication authenticate = authenticationManager.authenticate(authenticationToken);
            
            if (Objects.isNull(authenticate)) {
                return R.error(400, "用户名或密码错误");
            }

            // 获取用户信息
            User authenticatedUser = userService.getByUsername(user.getUname());

            // 更新登录信息

            // 使用TokenService生成和存储JWT令牌
            Map<String, Object> tokenResult = tokenService.generateTokens(user.getUname(), user.getUid());

            // 构建响应数据
            Map<String, Object> result = new HashMap<>();
            
            // 构建user信息
            Map<String, Object> userInfo = new HashMap<>();
            userInfo.put("userid", authenticatedUser.getUid());
            userInfo.put("username", authenticatedUser.getUname());
            userInfo.put("phone", authenticatedUser.getUphone());

            result.put("token", tokenResult.get("accessToken"));// JWT令牌
            result.put("user", userInfo);

            return R.success("登录成功", result);
        } catch (Exception e) {
            return R.error(500, "登录失败：" + e.getMessage());
        }
    }

    /**
     * 用户注册
     */
    @PostMapping("/register")
    public R<Map<String, Object>> register(@RequestBody LoginUser registerParams) {
        try {
            String userid = registerParams.getUserid();
            String username = registerParams.getUsername();
            String password = registerParams.getPassword();
            String phone = registerParams.getPhone();
            String smsCode = registerParams.getSmscode();



            // 验证短信验证码
            if (!smsCode.equals(stringRedisTemplate.opsForValue().get("SMS_CODE:" + phone))) {
                return R.error(400, "短信验证码不正确或已过期");
            }

            // 检查手机号是否已存在
            User existingUser = userService.getByPhone(phone);
            if (existingUser != null) {
                return R.error(400, "手机号已存在");
            }
            // 检查用户名是否已存在
            existingUser = userService.getByUsername(username);
            if (existingUser != null) {
                return R.error(400, "用户名已存在");
            }
            //检查用户ID是否已存在
            existingUser = userService.getById(userid);
            if (existingUser != null) {
                return R.error(400, "用户ID已存在");
            }
// 加密密码


            // 创建新用户
            User newUser = new User();
            // 注意：User实体类中使用的是uid而不是userid
            newUser.setUid(userid);
            newUser.setUname(username);
            newUser.setUpwd(password);
            newUser.setUphone(phone);

            boolean success = userService.addUser(newUser);
            if (success) {
                Map<String, Object> result = new HashMap<>();
                result.put("id", newUser.getUid());
                result.put("username", newUser.getUname());
                result.put("phone", newUser.getUphone());

                return R.success("注册成功", result);
            } else {
                return R.error("注册失败");
            }
        } catch (Exception e) {
            return R.error(500, "注册失败：" + e.getMessage());
        }
    }

    /**
     * 发送短信验证码
     */
    @PostMapping("/send-sms-code")
    public R<String> sendSmsCode(@RequestBody SendSmsRequest request) {
        // 验证手机号格式
        if (!isValidPhoneNumber(request.getPhoneNumber())) {
            return R.error(400, "手机号格式不正确");
        }

        // 发送6位验证码（保留一个发送方法）
        String code = smsService.sendSixDigitSmsCode(request.getPhoneNumber());

        if (code != null) {
            try {
                // 使用手机号作为key存储验证码，提高安全性
                stringRedisTemplate.opsForValue().set("SMS_CODE:" + request.getPhoneNumber(), code, 5, TimeUnit.MINUTES);
                return R.success("验证码发送成功",code);
            } catch (Exception e) {
                return R.error(500, "验证码存储失败");
            }
        } else {
            return R.error(500, "验证码发送失败，请稍后重试");
        }
    }

    /**
     * 验证手机号格式
     */
    private boolean isValidPhoneNumber(String phoneNumber) {
        return phoneNumber != null && phoneNumber.matches("^1[3-9]\\d{9}$");
    }

    @PostMapping("/reset-password")
    public R<String> resetPassword(@RequestBody ResetPasswordRequest request) {
        try {


            // 2. 验证账号和手机号是否匹配
            User user;
            // 判断userid是否是存在
            user = userService.getById(request.getUserid());
            if (user == null) {
                return R.error(400, "用户不存在");
            }
            //比对userid和手机号是否匹配
            if (!user.getUphone().equals(request.getPhone())) {
                return R.error(400, "账号和手机号不匹配");
            }
            // 1. 验证验证码是否正确
            String smsCodeKey = "SMS_CODE:" + request.getPhone();
            if (!stringRedisTemplate.hasKey(smsCodeKey)) {
                return R.error(400, "短信验证码不正确或已过期");
            }

            // 获取存储的验证码并验证
            String storedCode = stringRedisTemplate.opsForValue().get(smsCodeKey);
            if (!request.getSmscode().equals(storedCode)) {
                return R.error(400, "短信验证码不正确或已过期");
            }

            // 从Redis中删除已使用的验证码
            stringRedisTemplate.delete(smsCodeKey);

            // 3. 更新密码
            boolean success = userService.updatePassword(user.getUid(), request.getPassword());
            
            // 4. 返回结果
            return success ? R.success("密码重置成功",null) : R.error(500, "密码重置失败");
        } catch (Exception e) {
            return R.error(500, "密码重置失败：" + e.getMessage());
        }
    }



    

    //以下功能未开发，暂不实现

    /**
     * 修改密码
     */
    @PutMapping("/password")
    public R<String> changePassword(@RequestHeader("Authorization") String token, @RequestBody Map<String, String> params) {
        try {
            // 从SecurityContext中获取用户名
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            String username = authentication.getName();
            
            String oldPassword = params.get("oldPassword");
            String newPassword = params.get("newPassword");

            if (oldPassword == null || newPassword == null) {
                return R.error(400, "旧密码和新密码不能为空");
            }


            boolean success = userService.changePassword(username, oldPassword, newPassword);
            if (success) {
                return R.success("密码修改成功");
            } else {
                return R.error(400, "旧密码错误");
            }
        } catch (Exception e) {
            return R.error(500, "密码修改失败");
        }
    }



    /**
     * Token刷新
     */
    @PostMapping("/refresh")
    public R<Map<String, Object>> refreshToken(@RequestHeader("Authorization") String authHeader) {
        try {
            // 从请求头获取刷新token
            String refreshToken = null;
            if (authHeader != null && authHeader.startsWith("Bearer ")) {
                refreshToken = authHeader.substring(7);
            }

            if (refreshToken == null) {
                return R.error(400, "缺少刷新token");
            }

            // 使用TokenService刷新token
            Map<String, Object> result = tokenService.refreshToken(refreshToken);

            return R.success("令牌刷新成功", result);

        } catch (Exception e) {
            return R.error(401, "令牌刷新失败：" + e.getMessage());
        }
    }


    /**
     * 用户登出
     */
    @PostMapping("/logout")
    public R<String> logout(@RequestHeader("Authorization") String authHeader) {
        try {
            // 从SecurityContext中获取用户名
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            String username = authentication.getName();

            // 从请求头获取token
            String token = null;
            if (authHeader != null && authHeader.startsWith("Bearer ")) {
                token = authHeader.substring(7);
            }

            if (token == null) {
                return R.error(400, "缺少认证token");
            }

            // 撤销token
            tokenService.revokeToken(token, username);

            return R.success("退出成功");

        } catch (Exception e) {
            return R.error(500, "退出失败：" + e.getMessage());
        }
    }

    /**
     * 强制用户下线（管理员功能）
     */
    @PostMapping("/force-offline")
    public R<String> forceUserOffline(@RequestBody Map<String, Object> params) {
        try {
            // 检查当前用户权限（这里简化处理，实际应该检查管理员权限）
            String currentUsername = UserContext.getCurrentUsername();
            if (currentUsername == null) {
                return R.error(401, "未授权访问");
            }

            String targetUname = (String) params.get("username");
            String reason = (String) params.get("reason");

            if (targetUname == null || targetUname.trim().isEmpty()) {
                return R.error(400, "用户名不能为空");
            }

            if (reason == null || reason.trim().isEmpty()) {
                reason = "管理员强制下线";
            }

            // 强制用户下线
            tokenService.forceUserOffline(targetUname, reason);

            return R.success("用户已强制下线");

        } catch (Exception e) {
            return R.error(500, "操作失败：" + e.getMessage());
        }
    }

    /**
     * 获取在线用户统计
     */
    @GetMapping("/online-stats")
    public R<Map<String, Object>> getOnlineStats() {
        try {
            long onlineCount = tokenService.getOnlineUserCount();

            Map<String, Object> stats = new HashMap<>();
            stats.put("onlineUserCount", onlineCount);
            stats.put("timestamp", System.currentTimeMillis());

            return R.success("获取成功", stats);

        } catch (Exception e) {
            return R.error(500, "获取失败：" + e.getMessage());
        }
    }

    /**
     * 检查密码强度
     */
    @PostMapping("/check-password-strength")
    public R<Map<String, Object>> checkPasswordStrength(@RequestBody Map<String, String> params) {
        try {
            String password = params.get("password");
            if (password == null) {
                return R.error(400, "密码不能为空");
            }

            Map<String, Object> result = new HashMap<>();
            result.put("strength", PasswordUtil.checkPasswordStrength(password));
            result.put("strengthDescription", PasswordUtil.getUpwdStrengthDescription(password));
            result.put("isValid", PasswordUtil.isValidPassword(password));

            String validationError = PasswordUtil.getUpwdValidationError(password);
            if (validationError != null) {
                result.put("error", validationError);
            }

            return R.success("检查完成", result);
        } catch (Exception e) {
            return R.error(500, "密码强度检查失败：" + e.getMessage());
        }
    }

    /*
    忘记密码
     */






}